﻿/*
 * Copyright (c) Martin Kinkelin
 *
 * See the "License.txt" file in the root directory for infos
 * about permitted and prohibited uses of this code.
 */

using System;
using System.Collections.Generic;
using System.Xml;
using System.IO;

namespace Jarf
{
	/// <summary>
	/// Manages loading tasks from and saving tasks to an XML file.
	/// </summary>
	public class BackupTaskManager
	{
		private static readonly string PATH = "Jarf" + Path.DirectorySeparatorChar + "Tasks.xml";

		private static BackupTaskManager _instance;

		/// <summary>
		/// Gets the singleton instance.
		/// </summary>
		public static BackupTaskManager Instance
		{
			get
			{
				if (_instance == null)
					_instance = new BackupTaskManager();

				return _instance;
			}
		}



		private string _path;

		private BackupTaskManager()
		{
			_path = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), PATH);
		}


		/// <summary>
		/// Loads the tasks from the XML file.
		/// </summary>
		/// <returns></returns>
		public List<BackupTask> LoadTasks()
		{
			List<BackupTask> tasks = new List<BackupTask>();

			if (!File.Exists(_path))
				return tasks;

			XmlDocument document = new XmlDocument();
			document.Load(_path);

			XmlNodeList taskNodes = document.DocumentElement.SelectNodes("task");

			foreach (XmlNode node in taskNodes)
			{
				tasks.Add(BackupTask.Deserialize(node));
			}

			return tasks;
		}

		/// <summary>
		/// Loads the task with the specified GUID or null if it does not exist.
		/// </summary>
		/// <param name="guid"></param>
		/// <returns></returns>
		public BackupTask LoadTask(string guid)
		{
			if (string.IsNullOrEmpty(guid) || !File.Exists(_path))
				return null;

			XmlDocument document = new XmlDocument();
			document.Load(_path);

			XmlNode node = document.DocumentElement.SelectSingleNode(string.Format("task[@guid=\"{0}\"]", guid));

			return (node == null ? null : BackupTask.Deserialize(node));
		}


		/// <summary>
		/// Saves the specified tasks to the XML file.
		/// </summary>
		/// <param name="tasks"></param>
		public void SaveTasks(IEnumerable<BackupTask> tasks)
		{
			if (tasks == null)
				throw new ArgumentNullException("tasks");

			string directory = Path.GetDirectoryName(_path);
			if (!Directory.Exists(directory))
				Directory.CreateDirectory(directory);

			XmlDocument document = new XmlDocument();

			// create the document element
			document.AppendChild(document.CreateElement("tasks"));

			foreach (BackupTask task in tasks)
			{
				XmlElement node = document.CreateElement("task");
				task.Serialize(node);
				document.DocumentElement.AppendChild(node);
			}

			document.Save(_path);
		}

		/// <summary>
		/// Saves the specified task to the XML file.
		/// </summary>
		/// <param name="task"></param>
		public void SaveTask(BackupTask task)
		{
			if (task == null)
				throw new ArgumentNullException("task");

			XmlDocument document = new XmlDocument();
			document.Load(_path);

			XmlNode node = document.DocumentElement.SelectSingleNode(string.Format("task[@guid=\"{0}\"]", task.Guid));
			if (node != null)
			{
				// the backup task already exists in the file,
				// remove all attributes and children of the corresponding XML node
				node.RemoveAll();
			}
			else
			{
				node = document.CreateElement("task");
				document.DocumentElement.AppendChild(node);
			}

			task.Serialize(node);

			document.Save(_path);
		}
	}
}
